import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
array_1 = np.array([ i for i in range(0,51)])
array_2 = np.array([ (155 / 100) * (i - 50) + 100 for i in range(51,151)])
array_3 = np.array([i for i in range(151,256)])
transform = np.concatenate((array_1, array_2, array_3),axis=0).astype(np.uint8)
im = cv.imread(r"emma_gray.jpg", cv.IMREAD_GRAYSCALE)
assert im is not None
transformed_image = cv.LUT(im, transform)
fig, ax = plt.subplots(1, 3, figsize=(24, 6))
ax[0].plot(transform)
ax[0].set_title("Intensity Transformation")
ax[0].set_xlabel("Input Intensity")
ax[0].set_ylabel("Output Intensity")
ax[1].imshow(im, cmap="gray", vmin=0, vmax=255)
ax[1].set_title("Original Image")
ax[2].imshow(transformed_image, cmap="gray", vmin=0, vmax=255)
ax[2].set_title("Intensity Transformed Image")
for i in range(1,3):
ax[i].axis("off")
plt.show()
Discussion : We can see that, in this transformation function, pixels with intensity values between 50 and 150, are increased but other intensities are not changed. We can see this result in the above-transformed image. The intensities of gray pixels of the original image are increased so that we can see a clear white region on her face. But dark and white pixels are not changed.
im = cv.imread(r"brain_proton_density_slice.png", cv.IMREAD_GRAYSCALE)
assert im is not None
white_transform = np.array([((i / 255) ** 4) * 255 for i in range(0,256)],dtype=np.uint8)
white_transformed_image = cv.LUT(im, white_transform)
fig, ax = plt.subplots(1, 3, figsize=(24, 6))
fig.suptitle("Accentuate White Matter", fontsize=18)
ax[0].plot(white_transform)
ax[0].set_title("Intensity Transformation")
ax[0].set_xlabel("Input Intensity")
ax[0].set_ylabel("Output Intensity")
ax[1].imshow(im, cmap="gray", vmin=0, vmax=255)
ax[1].set_title("Original Image")
ax[2].imshow(white_transformed_image, cmap="gray", vmin=0, vmax=255)
ax[2].set_title("Accentuated White Matter")
for i in range(1,3):
ax[i].axis("off")
plt.show()
Discussion : In this transformation, we can see that a wide range of dark pixels are mapped into a narrow range of dark pixels and a narrow range of white pixels are mapped into a wide range of white pixels. Therefore, we can see that the details of white matter are more highlighted compared to gray matter. We can extract more information about white matters.
gray_transform = np.array([((i / 255) ** 0.3) * 255 for i in range(0,256)],dtype=np.uint8)
#gray_transform = np.array([255 - i for i in range(0,256)],dtype=np.uint8)
gray_transformed_image = cv.LUT(im, gray_transform)
fig, ax = plt.subplots(1, 3, figsize=(24, 6))
fig.suptitle("Accentuate Gray Matter", fontsize=18)
ax[0].plot(gray_transform)
ax[0].set_title("Intensity Transformation")
ax[0].set_xlabel("Input Intensity")
ax[0].set_ylabel("Output Intensity")
ax[1].imshow(im, cmap="gray", vmin=0, vmax=255)
ax[1].set_title("Original Image")
ax[2].imshow(gray_transformed_image, cmap="gray", vmin=0, vmax=255)
ax[2].set_title("Accentuated Gray Matter")
for i in range(1,3):
ax[i].axis("off")
plt.show()
Discussion : In this transformation, we can see that a narrow range of dark pixels are mapped into a wide range of dark pixels and a wide range of white pixels are mapped into a narrow range of white pixels. Therefore, we can see that the details of gray matter are more highlighted compared to white matter. We can extract more information about gray matters.
Question 03
im = cv.imread(r"highlights_and_shadows.jpg")
assert im is not None
LAB_image = cv.cvtColor(im, cv.COLOR_BGR2LAB)
original_hist = cv.calcHist([LAB_image], [0], None, [256], [0, 256])
gamma = 0.4
gamma_correction = np.array([((i / 255) ** gamma) * 255 for i in range(0,256)],dtype=np.uint8)
LAB_image[:, :, 0] = cv.LUT(LAB_image[:, :, 0], gamma_correction)
corrected_hist = cv.calcHist([LAB_image], [0], None, [256], [0, 256])
fig, ax = plt.subplots(1, 3, figsize=(24,6))
ax[0].plot(gamma_correction)
ax[0].set_title("Gamma Correction with $\gamma$ = {}".format(gamma))
ax[0].set_xlabel("Input Intensity")
ax[0].set_ylabel("Output Intensity")
ax[1].plot(original_hist)
ax[1].set_title("Histogram of Original Image")
ax[2].plot(corrected_hist)
ax[2].set_title("Histogram of Gamma Corrected Image")
plt.show()
fig, ax = plt.subplots(1, 2, figsize=(16,5))
ax[0].imshow(cv.cvtColor(im, cv.COLOR_BGR2RGB))
ax[0].set_title("Original Image")
ax[0].axis("off")
ax[1].imshow(cv.cvtColor(LAB_image, cv.COLOR_LAB2RGB))
ax[1].set_title("Gamma Corrected Image")
ax[1].axis("off")
plt.show()
Question 04
img = cv.imread(r"shells.png", cv.IMREAD_GRAYSCALE)
assert im is not None
original_hist = cv.calcHist([img], [0], None, [256], [0, 256])
cdf = original_hist.cumsum()
MN = img.shape[0] * img.shape[1]
equalize_transformation = np.array((cdf * 255) / MN, dtype=np.uint8)
equalize_img = cv.LUT(img, equalize_transformation)
equalize_hist = cv.calcHist([equalize_img], [0], None, [256], [0, 256])
fig, ax = plt.subplots(1, 4, figsize=(25,6))
ax[0].plot(original_hist)
ax[0].set_title("Histogram of the Original Image")
ax[1].plot(equalize_hist)
ax[1].set_title("Histogram of the Equalized Image")
ax[2].imshow(img, cmap="gray", vmin=0, vmax=255)
ax[2].set_title("Original Image")
ax[2].axis("off")
ax[3].imshow(equalize_img, cmap="gray", vmin=0, vmax=255)
ax[3].set_title("Equalized Image")
ax[3].axis("off")
plt.show()
import math
def nearestNeighborInterpolation(img, scale):
scaled_dimentions = (round(img.shape[0] * scale), round(img.shape[1] * scale), img.shape[2])
scaled_img = np.zeros(scaled_dimentions,dtype=np.uint8)
for i in range(scaled_dimentions[0]):
for j in range(scaled_dimentions[1]):
scaled_img[i, j] = img[min(round(i / scale), img.shape[0] - 1), min(round(j / scale), img.shape[1] - 1)]
return scaled_img
def bilinearInterpolation(img, scale):
scaled_dimentions = (round(img.shape[0] * scale), round(img.shape[1] * scale), img.shape[2])
scaled_img = np.zeros(scaled_dimentions,dtype=np.uint8)
x_ratio = (img.shape[1] - 1) / (scaled_dimentions[1] - 1)
y_ratio = (img.shape[0] - 1) / (scaled_dimentions[0] - 1)
for i in range(scaled_dimentions[0]):
for j in range(scaled_dimentions[1]):
x_floor = math.floor(j * x_ratio)
x_ceil = min(math.ceil(j * x_ratio), img.shape[1] - 1)
y_floor = math.floor(i * y_ratio)
y_ceil = min(math.ceil(i * y_ratio), img.shape[0] - 1)
x_weight = (j * x_ratio) - x_floor
y_weight = (i * y_ratio) - y_floor
pixel_value = img[y_floor, x_floor] * (1 - x_weight) * (1 - y_weight) + \
img[y_ceil, x_floor] * (x_weight) * (1 - y_weight) + \
img[y_floor, x_ceil] * (1 - x_weight) * (y_weight) + \
img[y_ceil, x_ceil] * (x_weight) * (y_weight)
scaled_img[i, j] = pixel_value
return scaled_img
def SSD(img1, img2):
return (np.power((img1 - img2), 2)).sum() / (img1.size)
fig, ax = plt.subplots(3, 3, figsize=(24, 15))
for i in range(3):
orig_img = cv.imread("a1q5images/a1q5images/im0{}.png".format(i+1))
orig_small_img = cv.imread("a1q5images/a1q5images/im0{}small.png".format(i+1))
assert orig_small_img is not None
nn_zoomed_img = nearestNeighborInterpolation(orig_small_img, 4)
bi_zoomed_img = bilinearInterpolation(orig_small_img, 4)
ax[i, 0].imshow(cv.cvtColor(orig_img, cv.COLOR_BGR2RGB))
ax[i, 0].set_title("Original Image")
ax[i, 1].imshow(cv.cvtColor(nn_zoomed_img, cv.COLOR_BGR2RGB))
ax[i, 1].set_title("Zoomed Image Using Nearest-Neighbor - SSD = {:.2f}".format(SSD(nn_zoomed_img, orig_img)))
ax[i, 2].imshow(cv.cvtColor(bi_zoomed_img, cv.COLOR_BGR2RGB))
ax[i, 2].set_title("Zoomed Image Using Bilinear Interpolation - SSD = {:.2f}".format(SSD(bi_zoomed_img, orig_img)))
plt.show()
img = cv.imread(r"einstein.png", cv.IMREAD_GRAYSCALE).astype(np.float32)
assert im is not None
sobel_v_kernel = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]], dtype=np.float32)
f_x = cv.filter2D(img, -1, sobel_v_kernel)
sobel_h_kernel = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]], dtype=np.float32)
f_y = cv.filter2D(img, -1, sobel_h_kernel)
grad_mag_img = np.sqrt(f_x**2 + f_y**2)
fig, ax = plt.subplots(1, 4, figsize=(30, 6))
fig.suptitle("Using existing filter2D", fontsize=18)
ax[0].imshow(img, cmap="gray", vmin=0, vmax=255)
ax[0].set_title("Original Image")
ax[1].imshow(f_x, cmap="gray", vmin=-1020, vmax=1020)
ax[1].set_title(r"Sobel Horizontal $f_x$")
ax[2].imshow(f_y, cmap="gray", vmin=-1020, vmax=1020)
ax[2].set_title(r"Sobel Vertical $f_y$")
ax[3].imshow(grad_mag_img, cmap="gray")
ax[3].set_title(r"Gradient Magnitude $\sqrt{f_x^2+f_y^2}$")
for i in range(4):
ax[i].axis("off")
plt.show()
def spacial_filter(img, kernel):
assert kernel.shape[0]%2 == 1 and kernel.shape[1]%2 == 1
kernel = np.rot90(np.rot90(kernel)) # rotate 180 for convolution
v_padding = int(kernel.shape[0] / 2)
h_padding = int(kernel.shape[1] / 2)
padded_img = np.zeros((img.shape[0] + 2 * v_padding, img.shape[1] + 2 * h_padding ), dtype=np.float32)
padded_img[v_padding:padded_img.shape[0] - v_padding, h_padding:padded_img.shape[1] - h_padding] = img
filtered_image = np.zeros(img.shape, dtype=np.float32)
for i in range(filtered_image.shape[0]):
for j in range(filtered_image.shape[1]):
filtered_image[i, j] = (kernel * padded_img[i: i + kernel.shape[0], j: j + kernel.shape[1]]).sum()
return filtered_image
f_x = spacial_filter(img, np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]], dtype=np.float32))
f_y = spacial_filter(img, np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]], dtype=np.float32))
grad_mag_img = np.sqrt(f_x**2 + f_y**2)
fig, ax = plt.subplots(1, 4, figsize=(30, 6))
fig.suptitle("Using Coded Filter Funtion", fontsize=18)
ax[0].imshow(img, cmap="gray", vmin=0, vmax=255)
ax[0].set_title("Original Image")
ax[1].imshow(f_x, cmap="gray", vmin=-1020, vmax=1020)
ax[1].set_title(r"Sobel Horizontal $f_x$")
ax[2].imshow(f_y, cmap="gray", vmin=-1020, vmax=1020)
ax[2].set_title(r"Sobel Vertical $f_y$")
ax[3].imshow(grad_mag_img, cmap="gray")
ax[3].set_title(r"Gradient Magnitude $\sqrt{f_x^2+f_y^2}$")
for i in range(4):
ax[i].axis("off")
plt.show()
f_y = spacial_filter(img, np.array([[1], [2], [1]], dtype=np.float32))
f_y = spacial_filter(f_y, np.array([[1, 0, -1]], dtype=np.float32))
f_x = spacial_filter(img, np.array([[1], [0], [-1]], dtype=np.float32))
f_x = spacial_filter(f_x, np.array([[1, 2, 1]], dtype=np.float32))
grad_mag_img = np.sqrt(f_x**2 + f_y**2)
fig, ax = plt.subplots(1, 4, figsize=(30, 6))
fig.suptitle("Using the Outer Product Property", fontsize=18)
ax[0].imshow(img, cmap="gray", vmin=0, vmax=255)
ax[0].set_title("Original Image")
ax[1].imshow(f_x, cmap="gray", vmin=-1020, vmax=1020)
ax[1].set_title(r"Sobel Horizontal $f_x$")
ax[2].imshow(f_y, cmap="gray", vmin=-1020, vmax=1020)
ax[2].set_title(r"Sobel Vertical $f_y$")
ax[3].imshow(grad_mag_img, cmap="gray")
ax[3].set_title(r"Gradient Magnitude $\sqrt{f_x^2+f_y^2}$")
for i in range(4):
ax[i].axis("off")
plt.show()
img = cv.imread(r"daisy.jpg")
assert im is not None
rect = (51,147,507,441)
mask = np.zeros(img.shape[:2], dtype=np.uint8)
x,y,w,h = rect
mask[y:y+h, x:x+w] = 1
fgModel = np.zeros((1, 65), dtype="float")
bgModel = np.zeros((1, 65), dtype="float")
cv.grabCut(img, mask, rect, bgModel,fgModel,iterCount=5, mode=cv.GC_INIT_WITH_RECT)
mask2 = np.where((mask==2)|(mask==0),0,1).astype(np.uint8)
foreground_img = img*mask2[:, :, np.newaxis]
background_img = img*(1 - mask2[:, :, np.newaxis])
fig, ax = plt.subplots(1, 4, figsize=(30, 18))
ax[0].imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))
ax[0].set_title("Original Image")
ax[1].imshow(mask2, cmap="gray")
ax[1].set_title("Final Segmentation Mask")
ax[2].imshow(cv.cvtColor(foreground_img, cv.COLOR_BGR2RGB))
ax[2].set_title("Foreground Image")
ax[3].imshow(cv.cvtColor(background_img, cv.COLOR_BGR2RGB))
ax[3].set_title("Background Image")
for i in range(4):
ax[i].axis("off")
plt.show()
background_blurred_img = cv.GaussianBlur(background_img, (13, 13), 8)
enhanced_img = foreground_img + background_blurred_img*(1 - mask2[:, :, np.newaxis])
fig, ax = plt.subplots(1, 2, figsize=(15, 18))
ax[0].imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))
ax[0].set_title("Original Image")
ax[1].imshow(cv.cvtColor(enhanced_img, cv.COLOR_BGR2RGB))
ax[1].set_title("Enhanced Image")
plt.show()